#pragma GCC optimize(2)
#include <graphics.h>//easyx图形化头文件
#include <iostream>
#include <Windows.h>
#include <mmsystem.h> // mci库头文件
#include<string>
#include <iomanip>
#include<vector>
#include<stdlib.h>

#include"Vector2.h"
#include"Atlas.h"

using namespace std;

bool running = true;
bool game_over = false;
int idx_current_anim = 0;

const int ScreenWidth = 1024;  const int ScreenHeight = 768;
const int BackgroundWidth = 620;  const int BackgroundHeight = 714;
const Vector2 BackgroundLeftTop(55, (ScreenHeight - BackgroundHeight) / 2);
const Vector2 BackgroundRightBottom(BackgroundLeftTop.x + BackgroundWidth, BackgroundLeftTop.y + BackgroundHeight);

const int graph_refreshing_rate = 60;   
const int delta = 1000 / graph_refreshing_rate;

//数值
float item_absorb_range = 75;//道具吸收范围
const float item_absorb_range_small = 75;
const float item_absorb_range_fullscreen = 2000;
const float item_caught_range = 7;//道具拾取范围
float POWERMAX = 5.00;//最大火力

int display_death;//显示敌人死亡数
int wave = 0;    //波数   
int enemy_level = 1;//敌人等级
const int enemy_max_level = 4;//敌人最大等级
const int boss_wave = 30;
static bool BOSS_MODE = false;
static bool DEVIL_BONUS = true;

int enemy_refrashing_timer = 10*delta;//刷怪间隔
const int enemy_refrashing_base_timer =10*delta;//基础刷怪间隔
int enemy_extra_spawn_rate = 2;//额外生成敌人数量

float Straight_Danmu_Speed = 3.0;//直线弹幕速度
float Straight_Sky_Danmu_Speed = 2.5;//天然弹幕速度
float Homing_Danmu_Speed = 3.5;//自机狙弹幕速度
int score = 0;   //分数
int target_score = 200000; //目标分数
int score_bonus = 0; //分数奖励次数

//波次影响函数
void wave_update()
{
    wave += 1;
}

void hardcore_update(int wave)
{
    (enemy_extra_spawn_rate < 3) ? enemy_extra_spawn_rate = wave / 20 : enemy_extra_spawn_rate = 3;
    (Straight_Danmu_Speed < 3.5) ? Straight_Danmu_Speed = 3 + wave / 50 : Straight_Danmu_Speed = 3.5;
    (Homing_Danmu_Speed < 6) ? Homing_Danmu_Speed = 3 + wave / 20 : Homing_Danmu_Speed = 6;
    (Straight_Sky_Danmu_Speed < 3) ? Straight_Sky_Danmu_Speed = 2 + wave / 50 : Straight_Sky_Danmu_Speed = 3;
	(enemy_level < enemy_max_level) ? enemy_level = wave / 35 + 1 : enemy_level = enemy_max_level;
}

//音乐播放函数
void MusicPlay()
{
    int bgm_num = (wave / boss_wave) % 5+1;
    if (wave / boss_wave >= 1)
    {
        std::wstring str = L"pause bgm0";
        int bgm_num_stop = (wave / boss_wave-1) % 5+1;
        str += (std::to_wstring(bgm_num_stop));
        mciSendString(str.c_str(), NULL, 0, NULL);
    }
    srand((unsigned)time(NULL));
    std::wstring str = L"play bgm0";
    str += (std::to_wstring(bgm_num) + L" repeat from 0");
    mciSendString(str.c_str(), NULL, 0, NULL);
}

#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"MSIMG32.LIB")

enum DanmuType{  Straight_Forward_Sky, Straight_Forward, Multi_Direction, Homing};
enum DanmuColor{ red, green, blue, yellow, purple};
enum DanmuAppearance{small_round,Troll};
enum EnemyType{	BlueFairy, RedFairy,GreatFairy,BOSS};
enum ItemType{  Power,Point,Hp,SP_POWER,SP_HEALTH};

class Player
{
public:
    const int PLAYER_WIDTH = 32;
    const int PLAYER_HEIGHT = 48;

    int HP = 3;//玩家血量
    bool is_invincible = false;//玩家无敌状态
    int invincible_time = 6 * delta;
    int counter = -1;

    float Damage = 3.50;//玩家伤害
    float Power = 1.00;//玩家火力
    float AttackSpeed = 2.73;//攻击速度
    float ShootingSpaceTime = 15;//射击间隔
public:
    void ShootingSpaceTimeUpdate(float val)
    {
        ShootingSpaceTime = 15 - sqrt(val - 1.0) * 5;
    }
 
    void DamageUpdate(float val)
    {
        Damage = 3.50 * (sqrt(val - 1.00) / 2 + 1.00);

    }

    void InvincibilityUpdate()
    {

        if (--counter <= 0&&is_invincible)
        {
            is_invincible = false;
        }
        else if (counter>0&&!is_invincible)
        {
            is_invincible = true;
        }
    }

    void Hurt()
    {
        if (!is_invincible)
        {
            HP -= 1;
            DEVIL_BONUS = false;
            is_invincible = true;
            counter = invincible_time;
            mciSendString(_T("play player_dead from 0"), NULL, 0, NULL);  //播放玩家死亡音效
        }
    }

    friend class Enemy;//友元类，敌人类可以访问玩家类的私有成员变量
    friend class Bullet;//友元类，子弹类可以访问玩家类的私有成员变量
    friend class Center;//友元类，中心类可以访问玩家类的私有成员变量
	friend class Spawn;//友元类，生成类可以访问玩家类的私有成员变量

public:
    Player()
    {
        anim_Koishi = new Animation(atlas_Koishi, 45);
        anim_left_Koishi = new Animation(atlas_left_Koishi, 45);
        anim_right_Koishi = new Animation(atlas_right_Koishi, 45);
    }

    ~Player()
    {
        delete anim_Koishi;
        delete anim_left_Koishi;
        delete anim_right_Koishi;
    }

    class Center
    {
    public:
        Vector2 Position;//判定点实际坐标为判定点中心
        const int RADIUS = 4;

    public:
        void GetPosition(Player &Player)
        {
            Position.x = Player.position.x + Player.PLAYER_WIDTH / 2;
            Position.y = Player.position.y + Player.PLAYER_HEIGHT / 2;

        }
        void Draw(Player &Player)
        {
            Vector2 DrawPosition;
            DrawPosition.x = Position.x - 5;
            DrawPosition.y=Position.y - 5 ;
            IMAGE img_center;
            loadimage(&img_center, _T("img/center.png"));
            if (Player.SLOW_MODE)
                putimage_alpha(DrawPosition, &img_center);
        }
    };

    class Bullet
    {
    public:
        Vector2 Position;
		Vector2 direction;
        int BULLET_WIDTH = 16;
        int BULLET_HEIGHT = 35;
        int BulletDamage = 3.5;//子弹伤害
    public:
        Bullet(const Player& Player,const int &list1)
        {
            if (list1 <= 2) 
            {
                anim_bullet = new Animation(atlas_bullet_main, 45);
                BulletDamage = Player.Damage;   BULLET_WIDTH = 16;  BULLET_HEIGHT = 35;
            }
            else 
            {
				anim_bullet = new Animation(atlas_bullet_sub, 45);
				BulletDamage = Player.Damage * 0.5; BULLET_WIDTH = 6; BULLET_HEIGHT = 30;
            }
			list = list1;
            GetPosition(Player,list);
        };

        ~Bullet()
        {
            delete anim_bullet;
        };

        void GetPosition(const Player& Player, const int& list)
        {
            switch (list) {
            case 1: Position.x = Player.position.x + 1; direction = { 0,-1 }; break;
            case 2: Position.x = Player.position.x + Player.PLAYER_WIDTH / 2 - 1; direction = { 0,-1 }; break;
            case 3: Position.x = Player.position.x - BULLET_WIDTH; direction = { 0,-1 }; break;
            case 4: Position.x = Player.position.x + Player.PLAYER_WIDTH ; direction = { 0,-1 }; break;
            case 5: Position.x = Player.position.x - BULLET_WIDTH; direction = { -1,-8 }; break;
            case 6: Position.x = Player.position.x + Player.PLAYER_WIDTH; direction = { 1,-8 }; break;
            case 7: Position.x = Player.position.x - BULLET_WIDTH + 2; direction = { -1,-2 }; break;
            case 8: Position.x = Player.position.x + Player.PLAYER_WIDTH - 2; direction = { 1,-2 }; break;
            case 9: Position.x = Player.position.x - BULLET_WIDTH + 2; direction = { -1,-3 }; break;
            case 10: Position.x = Player.position.x + Player.PLAYER_WIDTH - 2; direction = { 1,-3 }; break;
            default:break;
            }
            if (Player.SLOW_MODE)direction = { 0,-1 };
            Position.y = Player.position.y+Player.PLAYER_HEIGHT/2;
        }

        void Draw(int delta)
        {
            anim_bullet->Play(Position, delta);
        }

        void HitEnemy()
        {
            hit = true;
        }

        bool CheckDelete()
        {
            if (hit)return true;
            if (Position.y < 0)return true;
            return false;
        }

        void Move()
        {
			Position += direction.normalize() * BulletSpeed;
        }

    private:
        bool hit = false;
        Animation* anim_bullet;
        int list = 1;//子弹线序号
        const int BulletSpeed = 12;//弹速
    };

    void ProcessEvent(ExMessage& msg)
    {
        if (msg.message == WM_KEYDOWN)
        {
            switch (msg.vkcode)
            {
            case VK_UP:
                is_move_up = true;
                break;
            case VK_DOWN:
                is_move_down = true;
                break;
            case VK_LEFT:
                is_move_left = true;
                break;
            case VK_RIGHT:
                is_move_right = true;
                break;
            case 'W':
                is_move_up = true;
                break;
            case 'S':
                is_move_down = true;
                break;
            case 'A':
                is_move_left = true;
                break;
            case 'D':
                is_move_right = true;
                break;
            }
        }
        else if (msg.message == WM_KEYUP)
        {
            switch (msg.vkcode)
            {
            case VK_UP:
                is_move_up = false;
                break;
            case VK_DOWN:
                is_move_down = false;
                break;
            case VK_LEFT:
                is_move_left = false;
                break;
            case VK_RIGHT:
                is_move_right = false;
                break;
            case 'W':
                is_move_up = false;
                break;
            case 'S':
                is_move_down = false;
                break;
            case 'A':
                is_move_left = false;
                break;
            case 'D':
                is_move_right = false;
                break;
            }
        }


        if (msg.message == WM_KEYDOWN)
        {
            switch (msg.vkcode) {
            case VK_SHIFT:
                PLAYER_SPEED = PLAYER_SPEED_SLOW;
                SLOW_MODE = true;
                break;
            case 'K':
                PLAYER_SPEED = PLAYER_SPEED_SLOW;
                SLOW_MODE = true;
                break;
            case 'Z':
                SHOOTING = true;
                break;
            case 'J':
                SHOOTING = true;
                break;
            }
        }
        else if (msg.message == WM_KEYUP)
        {
            switch (msg.vkcode) {
            case VK_SHIFT:
                PLAYER_SPEED = PLAYER_SPEED_FAST;
                SLOW_MODE = false;
                break;
            case 'K':
                PLAYER_SPEED = PLAYER_SPEED_FAST;
                SLOW_MODE = false;
                break;
            case 'Z':
                SHOOTING = false;
                break;
            case 'J':
                SHOOTING = false;
                break;
            case'C':
                (HP > 9) ? HP = 999 : HP = 10;
                AttackSpeed = 5.0; 
				if (HP > 9)POWERMAX = 20;
                Power = POWERMAX;//ShootingSpaceTime = 1.0;
                ShootingSpaceTimeUpdate(AttackSpeed);
                DamageUpdate(Power);
                cout << "作弊模式开启状态变为true" << endl;
                break;
            case'V':
                for (int i = 1; i <= 5; i++)wave_update();
                break;
            case'B':
                for (int i = 1; ; i++)
                {
                    if (boss_wave * i > wave)
                    {
                        wave = boss_wave * i;
                        break;
                    }
                }
                break;
            }
        }
    }

    void Move()
    {
        int dir_x = is_move_right - is_move_left;
        int dir_y = is_move_down - is_move_up;
        double len_dir = sqrt(dir_x * dir_x + dir_y * dir_y);
        if (len_dir != 0)
        {
            double normalized_x = dir_x / len_dir;
            double normalized_y = dir_y / len_dir;//斜向速度平均化
            position.x += (PLAYER_SPEED * normalized_x);
            position.y += (PLAYER_SPEED * normalized_y);
        }

        if (position.x + PLAYER_WIDTH >= BackgroundRightBottom.x) position.x = BackgroundRightBottom.x - PLAYER_WIDTH;
        if (position.y + PLAYER_HEIGHT >= BackgroundRightBottom.y) position.y = BackgroundRightBottom.y - PLAYER_HEIGHT;
        if (position.x <= BackgroundLeftTop.x) position.x = BackgroundLeftTop.x;
        if (position.y <= BackgroundLeftTop.y) position.y = BackgroundLeftTop.y;

		position.y <= BackgroundLeftTop.y + 200 ? item_absorb_range = item_absorb_range_fullscreen : item_absorb_range = item_absorb_range_small;
    }

    void BulletSpawn(std::vector<Player::Bullet*>& bullet_list, Player& Player)
    {
        static int counter = 0;
        if ((++counter) % (int)Player.ShootingSpaceTime == 0)
        {
            for (int i = 1; i <= 2*((int)Player.Power-1) + 2&&i<=10; i++)
            {
                bullet_list.push_back(new Player::Bullet(Player, i));
            }
            mciSendString(_T("play player_shoot from 0"), NULL, 0, NULL);
        }
    }

    void Draw(int delta)
    {
        static bool facing_left = false;
        static bool facing_right = false;
        int direction_x = is_move_right - is_move_left;
        if (direction_x < 0)
        {
            facing_left = true;
            facing_right = false;
        }
        else if (direction_x > 0)
        {
            facing_left = false;
            facing_right = true;
        }
        else
        {
            facing_left = false;
            facing_right = false;
        }

        if (facing_left || facing_right) {
            if (facing_left)
                anim_left_Koishi->Play(position, delta);
            else
                anim_right_Koishi->Play(position, delta);
        }
        else
            anim_Koishi->Play(position, delta);
    }

private:
    const float PLAYER_SPEED_FAST = 8;
    const float PLAYER_SPEED_SLOW = 3;//速度
    float PLAYER_SPEED = PLAYER_SPEED_FAST;  //玩家移动速度
    Vector2 position = { (BackgroundLeftTop.x + BackgroundRightBottom.x) / 2, BackgroundRightBottom.y - 2 * PLAYER_HEIGHT };

private:
    IMAGE img_center;
    Animation* anim_Koishi;
    Animation* anim_left_Koishi;
    Animation* anim_right_Koishi;

    bool is_move_up = false;
    bool is_move_down = false;
    bool is_move_left = false;
    bool is_move_right = false;

    bool SLOW_MODE = false;//是否开启低速模式
    bool SHOOTING = false;//是否正在射击
};

class Obj
{
public: Obj() {};
      ~Obj() {};

      virtual void Effect(Player& Player){}

      virtual void Move(Player::Center&Center)
      {
          pos += direction * speed;
      }

      virtual bool CheckPlayerHitbox(const Player::Center& center)
      {
          return false;
      }

      void HitPlayer(Player& Player)
      {
          hit = true;
          Effect(Player);
      }

      bool CheckDelete()
      {
          if (pos.y > BackgroundLeftTop.y + BackgroundHeight + 100 || pos.y < -40 ||
              pos.x > BackgroundRightBottom.x + 40 || pos.x < BackgroundLeftTop.x - 40) return true;
          if ((pos.x > BackgroundLeftTop.x && pos.x < BackgroundRightBottom.x && pos.y > BackgroundLeftTop.y && pos.y < BackgroundLeftTop.y + BackgroundHeight) && hit)return true;
          return false;
      }

      void Draw(int delta)
      {
          anim->Play({ pos.x - Radius,pos.y - Radius }, delta);
      }

protected:
    int Radius;
    float speed;
    Animation* anim;
    bool hit = false;
    Vector2 pos;
    Vector2 direction;
};

class Danmaku :public Obj
{
public:
    Vector2 source_pos;  // 源位置(敌人位置)
    Vector2 target_pos;  // 目标位置(玩家位置)

    Danmaku(DanmuType type, DanmuColor color, DanmuAppearance appearance, const Vector2& source_pos, Vector2& set_direction, Player::Center &center,float obj_len)
    {
        Radius = Danmu_Small_Radius;
        if (color == red && appearance == small_round) anim = new Animation(atlas_danmu_red_small, 45);
        else if (color == blue && appearance == small_round) anim = new Animation(atlas_danmu_blue_small, 45);
        else if (color == green && appearance == small_round) anim = new Animation(atlas_danmu_green_small, 45);
        else if (appearance == Troll) { anim = new Animation(atlas_Troll, 45); Radius = Danmu_Troll_Radius; }
        pos.x = source_pos.x + obj_len/2;
        pos.y = source_pos.y + obj_len/2;
        target_pos = center.Position;
        switch (type) {
        case Homing:
            speed = Homing_Danmu_Speed;
            // 计算从敌人位置指向目标位置（玩家）的方向向量
            set_direction = (target_pos - pos).normalize();  // 归一化方向向量
            break;
        case Straight_Forward:
            speed = Straight_Danmu_Speed;
            set_direction = Vector2(0, 1);  // 直线弹幕默认向下
            break;
        case Straight_Forward_Sky:
            speed = Straight_Sky_Danmu_Speed;
            pos.x = rand() % (int)BackgroundWidth + BackgroundLeftTop.x;
            set_direction = Vector2(0, 1);  // 直线弹幕默认向下
            break;
        case Multi_Direction:
            speed = Straight_Danmu_Speed;
            break;
        }
        direction = set_direction;
    };

    ~Danmaku() = default;

public:
    void Move(Player::Center&Center)override
    {
        pos += direction * speed;
    }

    bool CheckPlayerHitbox(const Player::Center& center)override
    {
        bool is_center_inside = (pos - center.Position).length() < Radius - center.RADIUS;
        return is_center_inside;
    }

    void Effect(Player& Player)override
    {
        Player.Hurt();
    }

private:
    const int Danmu_Small_Radius = 8;
    const int Danmu_Troll_Radius = 20;
    DanmuType type;
    DanmuColor color;
    DanmuAppearance appearance;
};

class Item:public Obj
{
public:
    Vector2 source_pos;  // 源位置(敌人位置)
    float speed = fallenspeed;

    Item(const Vector2& source_pos, ItemType Type) :Type(Type)
    {
        Radius = Item_Width / 2;
        pos.x = source_pos.x + rand() % 32;
        pos.y = source_pos.y + rand() % 32;
        direction = { 0,1 };
        switch (Type)
        {
        case Point:
            anim = new Animation(atlas_item_point, 45); Item_Width = 16; Item_Height = 16; break;
        case Power:
            anim = new Animation(atlas_item_power, 45); Item_Width = 16; Item_Height = 16; break;
        case Hp:
            anim = new Animation(atlas_item_hp, 45); Item_Width = 32; Item_Height = 32; break;
        case SP_POWER:
            anim = new Animation(atlas_SP_POWER, 45); Item_Width = 60; Item_Height = 75; break;
        case SP_HEALTH:
            anim = new Animation(atlas_SP_HEALTH, 45); Item_Width = 60; Item_Height = 75; break;
		default:
            anim = nullptr; break;
        }
    }

    void Move(Player::Center& Center)override
    {
        float length = (pos-Center.Position).length();
        if (length > 0 && length <= item_absorb_range) {
            direction = { (Center.Position.x - pos.x) / length, (Center.Position.y - pos.y) / length };
            speed = length / 6 + 8;
        }
        else { direction = { 0,1 }; speed = fallenspeed; }
        pos += direction * speed;
        if(fallenspeed<=2.8)fallenspeed += 0.03;
    }

    bool CheckPlayerHitbox(const Player::Center& center)override
    {
        bool is_center_inside = (pos - center.Position).length() <= item_caught_range;
        return is_center_inside;
    }

    void Effect(Player& Player)override
    {
        switch (Type)
        {
        case(Power):
            Player.Power += 0.01;
            score += 50;
            if (Player.Power >= POWERMAX) { Player.Power = POWERMAX; score += 500; }
            Player.DamageUpdate(Player.Power);
            mciSendString(_T("play player_item from 0"), NULL, 0, NULL);
            break;
        case(Point):
            score += 1000;
            mciSendString(_T("play player_item from 0"), NULL, 0, NULL);
            break;
        case(Hp):
            Player.HP += 1;
            mciSendString(_T("play player_extend from 0"), NULL, 0, NULL);
            break;
        case(SP_POWER):
            Player.Power += 0.5;
            if (Player.Power >= POWERMAX) { POWERMAX+=1; }
            Player.DamageUpdate(Player.Power);
            Player.Hurt();
            break;
        case(SP_HEALTH):
            Player.HP += 1;
            mciSendString(_T("play player_extend from 0"), NULL, 0, NULL);
            break;
        }
    }

private:
    int Item_Width = 16;
    int Item_Height = 16;
    ItemType Type;
    float fallenspeed = -1.5; //道具下落速度
};

class Enemy
{
public:
    EnemyType GetType()const { return Type; }

    Vector2 pos;

    int Width = 10;
    int Height = 10;
    Vector2 direction;
    Vector2 set_danmu_direction;

    Enemy(const enum EnemyType Type) : Type(Type),
        anim_Enemy_left(nullptr),
        anim_Enemy_right(nullptr),
        pos{ 0, -30 }
    {
        set_danmu_direction = { 0,1 };
        if (Type == BlueFairy) {
            pos.x = rand() % (int)(BackgroundWidth - 80) + BackgroundLeftTop.x + 40;
            Width = enemy_small_width; Height = enemy_small_height;
            anim_Enemy = new Animation(atlas_BlueFairy, 45);
            anim_Enemy_left = new Animation(atlas_BlueFairy_left, 45);
            anim_Enemy_right = new Animation(atlas_BlueFairy_right, 45);

            health = 2 + enemy_level * 10;
            speedmax = 6;
            value = 60 * enemy_level;
            death_value = 1;

            danmu_string_num = 1;//连发上限
            danmu_num = 5 + enemy_level;
            delta_angle = 360 / danmu_num;

            shoot_timer = (160 + rand() % 40) * delta;      // 射击计时器
            shoot_interval = 240 * delta; // 射击间隔
        }
        else if (Type == RedFairy) {
            int side = rand() % 2;
            if (side == 0) { pos.y = rand() % 50 + BackgroundLeftTop.y + 30; pos.x = BackgroundLeftTop.x - 30; direction = { 1,0 }; }
            else if (side == 1) { pos.y = rand() % 50 + BackgroundLeftTop.y + 30; pos.x = BackgroundRightBottom.x; direction = { -1,0 }; }
            Width = enemy_small_width; Height = enemy_small_height;
            anim_Enemy = new Animation(atlas_RedFairy, 45);
            anim_Enemy_left = new Animation(atlas_RedFairy_left, 45);
            anim_Enemy_right = new Animation(atlas_RedFairy_right, 45);

            health = 4 + enemy_level * 7;
            speedmax = 2;
            value = 60 * enemy_level;
            death_value = 1;

            danmu_string_num = 2;//连发上限

            shoot_timer = 200 * delta;      // 射击计时器
            shoot_interval = 240 * delta; // 射击间隔（帧数）
        }
        else if (Type == GreatFairy) {
            pos.x = BackgroundLeftTop.x + (rand() % 3 + 1) * (BackgroundWidth / 4) - (pos.x + enemy_big_width / 2);
            anim_Enemy = new Animation(atlas_GreatFairy, 45);
            anim_Enemy_left = new Animation(atlas_GreatFairy_left, 45);
            anim_Enemy_right = new Animation(atlas_GreatFairy_right, 45);

            Width = enemy_big_width; Height = enemy_big_height;

            health = 105 + 100 * (enemy_level - 1);
            speedmax = 3;
            value = 400 * enemy_level;
            death_value = 5;

            danmu_string_num = 8;//连发上限
            danmu_num = 3 + enemy_level / 2;
            delta_angle = 360 / danmu_num;

            shoot_timer = 100 * delta;      // 射击计时器
            shoot_interval = 240 * delta; // 射击间隔
        }
        // shoot_timer = 0;
    }

    ~Enemy() = default;

    bool UpdateShootTimer(int delta)
    {
        shoot_timer += delta;
        if (shoot_timer >= shoot_interval)
        {
            shoot_timer = 0;
            return true;
        }
        return false;
    }

    void SingleDanmuSpawn(std::vector<Obj*>& objlist, DanmuType Type, DanmuColor Color, DanmuAppearance Appearance, Player::Center& Center)
    {
        Vector2 source_pos;
        source_pos.x = pos.x + Width / 2;
        source_pos.y = pos.y + Height / 2;
        Danmaku* danmu = new Danmaku(Type, Color, Appearance, pos, set_danmu_direction, Center, this->Width);
        objlist.push_back(danmu);
    }

    void ShootCircleDanmu(std::vector<Obj*>& objlist, DanmuColor Color, DanmuAppearance Appearance, Player::Center& Center)
    {
        set_danmu_direction.x = cos(angle / 360 * 2 * 3.14159);
        set_danmu_direction.y = sin(angle / 360 * 2 * 3.14159);
        SingleDanmuSpawn(objlist, Multi_Direction, Color, Appearance, Center);
    }

    virtual void Attack(std::vector<Obj*>& objlist, Player::Center& Center)
    {
        if (Type == BlueFairy) {
            while (UpdateShootTimer(delta) && danmu_string_num)
            {
                for (int i = 0; i < danmu_num; i++)
                {
                    angle += delta_angle;
                    ShootCircleDanmu(objlist, blue, small_round, Center);
                }
                mciSendString(_T("play se_tan from 0"), NULL, 0, NULL);
                shoot_timer = 230 * delta;
                if (--danmu_string_num > 0)speed = 0;
                else { speed = 1.5; is_move_down = true; }
            }
        }
        else if (Type == RedFairy) {
            while (UpdateShootTimer(delta) && danmu_string_num)
            {
                SingleDanmuSpawn(objlist, Homing, green, small_round, Center);
                mciSendString(_T("play se_tan from 0"), NULL, 0, NULL);
                shoot_timer = 180 * delta;
                danmu_string_num--;
            }
        }
        else if (Type == GreatFairy) {
            while (UpdateShootTimer(delta) && danmu_string_num)
            {
                for (int i = 0; i < danmu_num; i++)
                {
                    angle += delta_angle;
                    angle += 1;
                    ShootCircleDanmu(objlist, red, small_round, Center);
                }
                shoot_timer = 238 * delta;
                danmu_string_num--;
            }
            if (danmu_string_num <= 0)
            {
                shoot_timer = 220 * delta;
                danmu_string_num = 6;
            }
        }
    }

    virtual void Move(const enum EnemyType Type, const Player::Center& Center)
    {
        if (Type == BlueFairy) {
            if (is_move_down)direction = { 0,1 };
            else
            {
                direction.x = Center.Position.x - (pos.x + enemy_small_width / 2);
                direction.y = Center.Position.y - (pos.y + enemy_small_height / 2);
                speed = sin((BackgroundLeftTop.y + BackgroundHeight / 4 - pos.y) / (BackgroundLeftTop.y + BackgroundHeight / 4) * 3.14159 / 2) * speedmax;
            }

        }
        else if (Type == GreatFairy)
        {
            direction = { 0,1 };
            if (pos.y <= BackgroundLeftTop.y + BackgroundHeight / 5)speed = sin((BackgroundLeftTop.y + BackgroundHeight / 5 - pos.y) / (BackgroundLeftTop.y + BackgroundHeight / 5) * 3.14159 / 2) * speedmax;
        }
        pos += direction.normalize() * speed;
    }

    void Draw(int delta)
    {
        if (direction.normalize().x < -0.2)
            anim_Enemy_left->Play(pos, delta);
        else if (direction.normalize().x > 0.2)
            anim_Enemy_right->Play(pos, delta);
        else anim_Enemy->Play(pos, delta);
    }

    bool CheckBulletHitbox(const Player::Bullet& bullet)
    {
        bool is_inside_x = bullet.Position.x + bullet.BULLET_WIDTH / 2 >= pos.x &&
            bullet.Position.x + bullet.BULLET_WIDTH / 2 <= pos.x + Width;
        bool is_inside_y = bullet.Position.y >= pos.y + 5 &&
            bullet.Position.y <= pos.y + Height - 5;
        return is_inside_x && is_inside_y;
    }

    bool CheckPlayerHitbox(const Player::Center& center)
    {
        bool is_center_inside_x = center.Position.x >= pos.x &&
            center.Position.x + center.RADIUS <= pos.x + enemy_small_width;
        bool is_center_inside_y = center.Position.y >= pos.y &&
            center.Position.y + center.RADIUS <= pos.y + enemy_small_height;
        return is_center_inside_x && is_center_inside_y;
    }

    bool CheckAlive()
    {
        if (!Alive)return false;
        return true;
    }

    bool CheckOutofRange()
    {
        if (pos.y > BackgroundRightBottom.y)return true;
        if (pos.x > BackgroundRightBottom.x + 60 || pos.x < BackgroundLeftTop.x - 60)return true;
        return false;
    }

    bool CheckDelete() {
        return !CheckAlive() || CheckOutofRange();
    }

    virtual void Hurt(float damage)
    {
        health -= damage;
        if (health <= 0)Alive = false;
    }

    virtual void DeathEffect(const Enemy& enemy, std::vector<Obj*>& objlist, Player& Player, Player::Center& Center)
    {
        mciSendString(_T("play enemy_death from 0"), NULL, 0, NULL);  //播放敌人死亡音效
        score += value;
        display_death++;
        while (death_value--)
        {

            if (rand() % 100 <= 40) {
                for (int i = 1, base_possibility = 100; i <= 3; i++)
                {
                    if (rand() % 100 <= base_possibility)
                    {
                        Item* item = new Item(pos, Point);
                        objlist.push_back(item);
                        base_possibility -= 40;
                    }
                }
            }
            if (rand() % 100 <= 40)
            {
                for (int i = 1, base_possibility = 100; i <= 2; i++)
                {
                    if (rand() % 100 <= base_possibility)
                    {
                        Item* item = new Item(pos, Power);
                        objlist.push_back(item);
                        base_possibility -= 20;
                    }
                }
            }
        }
        if (Player.AttackSpeed < 5.0) { Player.AttackSpeed += 0.01 * enemy_level; Player.ShootingSpaceTimeUpdate(Player.AttackSpeed); } //射速提升
        if (Player.AttackSpeed >= 5.0) { Player.AttackSpeed = 5.0; Player.ShootingSpaceTimeUpdate(Player.AttackSpeed); } //射速上限
    }

protected:
    EnemyType Type;

    float health = 10;
    bool Alive = true;
    double speed = 2;//敌人速度
    double speedmax = 2;
    int shoot_timer = 0 * delta;      // 射击计时器
    int shoot_interval = 120 * delta; // 射击间隔（帧数）
    int danmu_string_num = 1;
    int danmu_num = 6;
    float delta_angle = 360 / danmu_num;
    float angle = rand() % 360;
    float spin_speed = 120;

    int value = 100;
    int death_value = 1;
protected:
    Animation* anim_Enemy;
    Animation* anim_Enemy_left;
    Animation* anim_Enemy_right;
    bool is_move_up = false;
    bool is_move_down = false;
    bool is_move_left = false;
    bool is_move_right = false;

    const int enemy_small_height = 30;
    const int enemy_small_width = 30;
    const int enemy_big_height = 60;
    const int enemy_big_width = 60;
    const int enemy_boss_height = 64;
    const int enemy_boss_width = 64;

};

class Boss :public Enemy
{
public:

    Boss(const enum EnemyType Type) :Enemy(Type)
    {
        pos.x = BackgroundLeftTop.x + BackgroundWidth / 2 - (pos.x + enemy_boss_width / 2);
        anim_Enemy = new Animation(atlas_Boss, 45);
        anim_Enemy_left = new Animation(atlas_Boss_left, 45);
        anim_Enemy_right = new Animation(atlas_Boss_right, 45);
        
        Width = enemy_boss_width; Height = enemy_boss_height;

        SpellCard_max = enemy_level;
        (SpellCard_max >= 3) ? SpellCard_max = 3 : SpellCard_max = enemy_level;
        health = health_max + 150;
        value = 6000 * enemy_level;

        danmu_string_num = 300 + wave;//连发上限
        danmu_num = enemy_level + 1;
        delta_angle = 360 / danmu_num;

        shoot_timer = 90 * delta;      // 射击计时器
        shoot_interval = 240 * delta; // 射击间隔
    }

	~Boss() = default;

    bool UpdateHomingShootTimer(int delta)
    {
        homing_shoot_timer += delta;
        if (homing_shoot_timer >= shoot_interval)
        {
            homing_shoot_timer = 0;
            return true;
        }
        return false;
    }

    void Attack(std::vector<Obj*>& objlist, Player::Center& Center)override
    {
        while (UpdateShootTimer(delta) && danmu_string_num)
        {
            switch (SpellCard)
            {
            case 1:
            {

                for (int i = 0; i < danmu_num - 1; i++)
                {
                    angle = rand() % 360;
                    ShootCircleDanmu(objlist, blue, small_round, Center);
                }
                break;
            }
            case 2:
            {
                danmu_string_num = 300;
                delta_angle = 360 / (danmu_num - 1);
                for (int i = 0; i < danmu_num - 1; i++)
                {
                    angle += delta_angle;
                    angle += 0.35;
                    ShootCircleDanmu(objlist, blue, small_round, Center);
                }
                while (UpdateHomingShootTimer(delta) && danmu_string_num)
                {
                    SingleDanmuSpawn(objlist, Homing, blue, Troll, Center);
                    mciSendString(_T("play se_tan from 0"), NULL, 0, NULL);
                    homing_shoot_timer = 140 * delta;
                    danmu_string_num--;
                }
                break;
            }
            case 3:
            {
                delta_angle = (360 / danmu_num - 2);
                spin_speed += 0.05;
                for (int i = 0; i < danmu_num - 2; i++)
                {
                    angle += spin_speed;
                    ShootCircleDanmu(objlist, blue, small_round, Center);
                }
                break;
            }
            }
            shoot_timer = 238 * delta;
            danmu_string_num--;
            // mciSendString(_T("play se_tan from 100"), NULL, 0, NULL);
        }
        if (danmu_string_num <= 0)
        {
            shoot_timer = 200 * delta;
            danmu_string_num = 300;
        }
    }

    void Move(const enum EnemyType Type, const Player::Center& Center)override
    {
        direction = { 0,1 };
        if (pos.y <= BackgroundLeftTop.y + BackgroundHeight / 4)speed = sin((BackgroundLeftTop.y + BackgroundHeight / 4-pos.y)/ (BackgroundLeftTop.y + BackgroundHeight / 4)*3.14159/2)*speedmax;
		else speed = 0;
        pos += direction.normalize() * speed;
    }

    void Hurt(float damage)override
    {
        health -= damage;
        if (health <= 0) {
            SpellCard++;
            if (SpellCard >SpellCard_max)Alive = false;
            else {
                mciSendString(_T("play boss_change from 0"), NULL, 0, NULL);  //播放敌人转阶段
                score += value * enemy_level;
                health = health_max;
                shoot_timer = 100 * delta;
                homing_shoot_timer = 0;
            }
        }
    }

    void DeathEffect(const Enemy& enemy, std::vector<Obj*>& objlist, Player& Player, Player::Center& Center)override
    {
        mciSendString(_T("play enemy_death from 0"), NULL, 0, NULL);  //播放敌人死亡音效
        score += value * enemy_level;
        display_death++;

        wave_update();
        MusicPlay();

        while (num_of_boss_power-- >= 0)
        {
            Item* item = new Item(pos, Power);
            objlist.push_back(item);
        }

        if (DEVIL_BONUS)
        {
            Item* SP1 = new Item({ BackgroundLeftTop.x + BackgroundWidth / 4,0 }, SP_POWER);
            objlist.push_back(SP1);
            Item* SP2 = new Item({ BackgroundLeftTop.x + BackgroundWidth * 3 / 4,0 }, SP_HEALTH);
            objlist.push_back(SP2);
        }
        BOSS_MODE = false;
        DEVIL_BONUS = true;
        return;
    }
private:
    int SpellCard = 1;
	int SpellCard_max = 3;
    int health_max = 325 + (enemy_level - 1) * 800;
    double speedmax = 3;
    int num_of_boss_power = 15;
	int homing_shoot_timer = 0 * delta;      // 自机狙计时器
};

class LoadMaterial
{
public:
    //加载图片素材
    void load_picture_material()
    {
        loadimage(&img_background_final, _T("img/BG/Background_FinalDark.png"));
        loadimage(&img_stage1_background, _T("img/BG/Background1Dark.jpg"));
        loadimage(&img_stage2_background, _T("img/BG/Background2Dark.png"));
		loadimage(&img_stage3_background, _T("img/BG/Background3Dark.png"));
        loadimage(&img_stage4_background, _T("img/BG/Background4Dark.png"));
        loadimage(&MenuBG, _T("img/MenuBG.png"));
        loadimage(&img_interface, _T("img/Interface00.png"));
    }

    //加载音乐和音效 
    void load_audio_material()
    {
        mciSendString(_T("open mus/Stage01.mp3 alias bgm01"), NULL, 0, NULL);
        mciSendString(_T("setaudio bgm01 volume to 300"), NULL, 0, NULL);
        mciSendString(_T("open mus/Stage02.mp3 alias bgm02"), NULL, 0, NULL);
        mciSendString(_T("setaudio bgm02 volume to 300"), NULL, 0, NULL);
        mciSendString(_T("open mus/Stage03.mp3 alias bgm03"), NULL, 0, NULL);
        mciSendString(_T("setaudio bgm03 volume to 400"), NULL, 0, NULL);
        mciSendString(_T("open mus/Stage04.mp3 alias bgm04"), NULL, 0, NULL);
        mciSendString(_T("setaudio bgm04 volume to 300"), NULL, 0, NULL);
        mciSendString(_T("open mus/Stage05.mp3 alias bgm05"), NULL, 0, NULL);
        mciSendString(_T("setaudio bgm05 volume to 300"), NULL, 0, NULL);
        mciSendString(_T("open mus/Stage06.mp3 alias bgm06"), NULL, 0, NULL);
        mciSendString(_T("setaudio bgm06 volume to 300"), NULL, 0, NULL);

        mciSendString(_T("open mus/start_menu.mp3 alias start_menu"), NULL, 0, NULL);
        mciSendString(_T("setaudio start_menu volume to 400"), NULL, 0, NULL);
        mciSendString(_T("open mus/game_over.mp3 alias game_over"), NULL, 0, NULL);
        mciSendString(_T("setaudio game_over volume to 400"), NULL, 0, NULL);

        mciSendString(_T("open mus/enemy_death.mp3 alias enemy_death"), NULL, 0, NULL);
        mciSendString(_T("setaudio enemy_death volume to 140"), NULL, 0, NULL);
        mciSendString(_T("open mus/se_tan.mp3 alias se_tan"), NULL, 0, NULL);
        mciSendString(_T("setaudio se_tan volume to 80"), NULL, 0, NULL);
        mciSendString(_T("open mus/boss_change.mp3 alias boss_change"), NULL, 0, NULL);
        mciSendString(_T("setaudio boss_change volume to 400"), NULL, 0, NULL);
        mciSendString(_T("open mus/player_shoot.mp3 alias player_shoot"), NULL, 0, NULL);
        mciSendString(_T("setaudio player_shoot volume to 120"), NULL, 0, NULL);
        mciSendString(_T("open mus/player_dead.mp3 alias player_dead"), NULL, 0, NULL);
        mciSendString(_T("setaudio player_dead volume to 120"), NULL, 0, NULL);
        mciSendString(_T("open mus/player_item.mp3 alias player_item"), NULL, 0, NULL);
        mciSendString(_T("setaudio player_item volume to 50"), NULL, 0, NULL);
        mciSendString(_T("open mus/player_extend.mp3 alias player_extend"), NULL, 0, NULL);
        mciSendString(_T("setaudio player_extend volume to 120"), NULL, 0, NULL);
    }

public:
    IMAGE img_background_final;
    IMAGE img_stage1_background;
    IMAGE img_stage2_background;
	IMAGE img_stage3_background;
	IMAGE img_stage4_background;
    IMAGE MenuBG;
    IMAGE img_interface;
};

class Render
{
public:
    //绘制图片函数
    void DrawPicture(LoadMaterial& TH, Player& Player, Player::Center Center,
        std::vector<Enemy*>enemylist, std::vector<Player::Bullet*>bulletlist,
        std::vector<Obj*>& objlist)
    {
        switch (((wave - 1) / boss_wave + 1) % 5)
        {
        case 1:putimage((int)BackgroundLeftTop.x, (int)BackgroundLeftTop.y, &TH.img_stage1_background); break;
        case 2:putimage((int)BackgroundLeftTop.x, (int)BackgroundLeftTop.y, &TH.img_stage2_background); break;
        case 3:putimage((int)BackgroundLeftTop.x, (int)BackgroundLeftTop.y, &TH.img_stage3_background); break;
        case 4:putimage((int)BackgroundLeftTop.x, (int)BackgroundLeftTop.y, &TH.img_stage4_background); break;
        default:putimage((int)BackgroundLeftTop.x, (int)BackgroundLeftTop.y, &TH.img_background_final);  break;
        }
        for (Player::Bullet* Bullet : bulletlist)
            Bullet->Draw(delta);
        for (Enemy* Fairy : enemylist)
            Fairy->Draw(delta);
        Player.Draw(delta);
        for (Obj* obj : objlist) obj->Draw(delta);
        Center.Draw(Player);
        putimage_alpha(Vector2(0, 0), &TH.img_interface);
    }

    //绘制提示信息函数
    void DrawTextTip(Player& Player)
    {
        static TCHAR str[64];
        _stprintf_s(str, _T("当前波数：%d"), wave);
        settextcolor(RGB(225, 175, 45));
        outtextxy(ScreenWidth - 250, 30, str);
        _stprintf_s(str, _T("敌人击杀数：%d"), display_death);
        settextcolor(RGB(225, 175, 45));
        outtextxy(ScreenWidth - 250, 50, str);
        _stprintf_s(str, _T("Score：%d"), score);
        settextcolor(RGB(225, 175, 45));
        outtextxy(ScreenWidth - 250, 70, str);
        _stprintf_s(str, _T("目标分数：%d"), target_score);
        settextcolor(RGB(225, 175, 45));
        outtextxy(ScreenWidth - 250, 90, str);
        _stprintf_s(str, _T("剩余生命：%d"), Player.HP);
        settextcolor(RGB(225, 175, 45));
        outtextxy(ScreenWidth - 250, 110, str);
        _stprintf_s(str, _T("当前射速：%.2f"), Player.AttackSpeed);
        settextcolor(RGB(225, 175, 45));
        outtextxy(ScreenWidth - 250, 150, str);
        _stprintf_s(str, _T("当前射击间隔：%.2f"), Player.ShootingSpaceTime);
        settextcolor(RGB(225, 175, 45));
        outtextxy(ScreenWidth - 250, 170, str);
        _stprintf_s(str, _T("当前火力：%.2f/%.2f"), Player.Power, POWERMAX);
        settextcolor(RGB(225, 175, 45));
        outtextxy(ScreenWidth - 250, 190, str);
        _stprintf_s(str, _T("当前子弹伤害：%.2f"), Player.Damage);
        settextcolor(RGB(225, 175, 45));
        outtextxy(ScreenWidth - 250, 210, str);
        _stprintf_s(str, _T("Z射击  SHIFT减速  上下左右移动"));
        settextcolor(RGB(225, 175, 45));
        outtextxy(ScreenWidth - 250, 230, str);
    }
};

class Spawn
{
public:
    //单个敌人生成函数
    void EnemySpawn(std::vector<Enemy*>& enemylist, const enum EnemyType Type, int enemy_spawn_num)
    {
        while(--enemy_spawn_num>=0)enemylist.push_back(new Enemy(Type));    
    };

    //天然弹幕生成函数
    void NatureDanmuSpawn(std::vector<Obj*>& objlist, DanmuType Type, DanmuColor Color, DanmuAppearance Appearance, Player::Center& Center, int wave)
    {
        int danmu_refrashing_timer = 130 - wave / 2;
        (danmu_refrashing_timer < 10) ? danmu_refrashing_timer = 10 : danmu_refrashing_timer = danmu_refrashing_timer ;
        static int counter = 0;
        Vector2 vec = { 0,0 };
        if ((++counter) % danmu_refrashing_timer == 0)
            objlist.push_back(new Danmaku(Type, Color, Appearance, vec, vec, Center,0));
    };

    //敌弹生成函数
    void EnemyDanmuSpawn(std::vector<Enemy*>& Enemylist, std::vector<Obj*>& objlist, Player::Center& Center)
    {
        for (Enemy* enemy : Enemylist)
        {
            enemy->Attack(objlist, Center);
        }
    }

    //对象生成函数
    void ObjectSpawn(std::vector<Enemy*>& enemylist, std::vector<Player::Bullet*>& bulletlist,
        Player& Player, Player::Center& Center, std::vector<Obj*>& objlist)
    {
        static int counter = 0; 
        //敌人生成
        if ((++counter) % enemy_refrashing_timer == 0 && !BOSS_MODE)
        {
            for (int i = 1; i <= 2; i++)
            {
                if (wave % boss_wave == 0 && wave > 0) { for (Enemy* enemy : enemylist) { enemy->Hurt(114514); }enemylist.push_back(new Boss(BOSS)); BOSS_MODE = true; break; }
                else if (rand() % 10 <= 3) EnemySpawn(enemylist, RedFairy, 2+enemy_extra_spawn_rate);
                else if (rand() % 10 >= 8) EnemySpawn(enemylist, GreatFairy, 1);
                else EnemySpawn(enemylist, BlueFairy, 1+enemy_extra_spawn_rate);
            }
            if(!BOSS_MODE)wave_update();
            hardcore_update(wave);
        }
        //玩家子弹生成
        if (Player.SHOOTING)  Player.BulletSpawn(bulletlist, Player);

        //敌人弹幕生成
        EnemyDanmuSpawn(enemylist, objlist, Center); //敌人发射弹幕
        if (!BOSS_MODE)NatureDanmuSpawn(objlist, Straight_Forward_Sky, blue, small_round, Center, wave);//天然弹幕
    }

	//对象移动函数
	void ObjectMove(std::vector<Enemy*>& enemylist, std::vector<Player::Bullet*>& bulletlist,
		Player& Player, Player::Center& Center, std::vector<Obj*>& objlist)
	{
        Player.Move();
        Center.GetPosition(Player);
        for (Player::Bullet* Bullet : bulletlist)    Bullet->Move();
		for (Enemy* enemy : enemylist)enemy->Move(enemy->GetType(), Center);
		for (Obj* obj : objlist)obj->Move(Center);
	}

    //对象生命判定函数
    void ObjectLifeJudgement(std::vector<Enemy*>& enemylist, std::vector<Player::Bullet*>& bulletlist,
        Player& Player, Player::Center& Center, std::vector<Obj*>& objlist)
    {
        //玩家无敌状态更新
        Player.InvincibilityUpdate();
        //玩家失败判定
        if (Player.HP <= 0) { game_over = true; }
        //玩家受敌人碰撞检测
        for (Enemy* enemy : enemylist)
        {
            if (enemy->CheckPlayerHitbox(Center))
            {
                Player.Hurt();
                break;
            }
        }

        //玩家受弹幕或物品碰撞检测
        for (Obj*obj : objlist)
        {
            if (obj->CheckPlayerHitbox(Center))
            {
                obj->HitPlayer(Player);
            }
        }

        //敌人受击检测+子弹命中检测
        for (Enemy* enemy : enemylist)
        {
            for (Player::Bullet* Bullet : bulletlist)
            {
                if (enemy->CheckBulletHitbox(*Bullet))
                {
                    enemy->Hurt(Bullet->BulletDamage);
                    Bullet->HitEnemy();
                    for (size_t i = 0; i < enemylist.size(); i++) {
                        Enemy* enemy = enemylist[i];
                        //敌人存活检测，为否则进行死亡判定
                        if (!enemy->CheckAlive())
                        {
                            enemy->DeathEffect(*enemy, objlist, Player, Center);
                            std::swap(enemylist[i], enemylist.back());
                            enemylist.pop_back();
                            delete enemy;
                        }
                    }
                }
            }
        }

        //敌人对象删除判定
        for (size_t i = 0; i < enemylist.size(); i++)
        {
            Enemy* enemy = enemylist[i];
            if (enemy->CheckDelete())
            {
                std::swap(enemylist[i], enemylist.back());
                enemylist.pop_back();
                delete enemy;
            }
        }

        //弹幕或物品对象删除判定
        for (size_t i = 0; i < objlist.size(); i++)
        {
            Obj* obj = objlist[i];
            if (obj->CheckDelete())
            {
                std::swap(objlist[i], objlist.back());
                objlist.pop_back();
                delete obj;
            }
        }

        //子弹对象删除判定
        for (size_t i = 0; i < bulletlist.size(); i++)
        {
            Player::Bullet* Bullet = bulletlist[i];
            if (Bullet->CheckDelete())
            {
                std::swap(bulletlist[i], bulletlist.back());
                bulletlist.pop_back();
                delete Bullet;
            }
        }   
    }
};

int main() {
    initgraph(ScreenWidth, ScreenHeight);//创建窗口

    atlas_Koishi = new Atlas(_T("img/Koishi/Koishi_%d.png"), 8); atlas_left_Koishi = new Atlas(_T("img/Koishi/Koishi_left_%d.png"), 8);    atlas_right_Koishi = new Atlas(_T("img/Koishi/Koishi_right_%d.png"), 8);
    atlas_BlueFairy = new Atlas(_T("img/Enemy/Enemy_BlueFairy/EnemyB_%d.png"), 5);    atlas_BlueFairy_left = new Atlas(_T("img/Enemy/Enemy_BlueFairy/EnemyB_left_%d.png"), 7);    atlas_BlueFairy_right = new Atlas(_T("img/Enemy/Enemy_BlueFairy/EnemyB_right_%d.png"), 7);
    atlas_RedFairy = new Atlas(_T("img/Enemy/Enemy_RedFairy/Enemy_RedFairy_%d.png"), 5);    atlas_RedFairy_left = new Atlas(_T("img/Enemy/Enemy_RedFairy/Enemy_RedFairy_left_%d.png"), 7);    atlas_RedFairy_right = new Atlas(_T("img/Enemy/Enemy_RedFairy/Enemy_RedFairy_right_%d.png"), 7);
    atlas_GreatFairy=new Atlas(_T("img/Enemy/Enemy_GreatFairy/Enemy_GreatFairy_%d.png"), 5);  atlas_GreatFairy_left = new Atlas(_T("img/Enemy/Enemy_GreatFairy/Enemy_GreatFairy_left_%d.png"), 7); atlas_GreatFairy_right = new Atlas(_T("img/Enemy/Enemy_GreatFairy/Enemy_GreatFairy_right_%d.png"), 7);
	atlas_Boss = new Atlas(_T("img/Enemy/Boss/Boss_%d.png"), 4);    atlas_Boss_left = new Atlas(_T("img/Enemy/Boss/Boss_left_%d.png"), 4);    atlas_Boss_right = new Atlas(_T("img/Enemy/Boss/Boss_right_%d.png"), 4);
    atlas_bullet_main = new Atlas(_T("img/BulletPurple_%d.png"), 1);	atlas_bullet_sub = new Atlas(_T("img/BulletBlueSmall_%d.png"), 1);
    atlas_danmu_red_small = new Atlas(_T("img/Danmaku/red_small_round_%d.png"), 1);    atlas_danmu_blue_small = new Atlas(_T("img/Danmaku/blue_small_round_%d.png"), 1);	atlas_danmu_green_small = new Atlas(_T("img/Danmaku/green_small_round_%d.png"), 1);
    atlas_Troll = new Atlas(_T("img/Danmaku/Troll_%d.png"), 1);
    atlas_item_hp = new Atlas(_T("img/Item/Item_Hp_%d.png"), 1);    atlas_item_power = new Atlas(_T("img/Item/Item_Power_%d.png"), 1);    atlas_item_point = new Atlas(_T("img/Item/Item_Point_%d.png"), 1);
    atlas_SP_POWER = new Atlas(_T("img/Item/SP/CIRNO_POWER_%d.png"), 1);    atlas_SP_HEALTH = new Atlas(_T("img/Item/SP/EXTEND_CARD_%d.png"), 1);

    LoadMaterial TouhouMaterial;
    TouhouMaterial.load_picture_material();
    TouhouMaterial.load_audio_material();//加载文件
   

    Player Koishi;
    Player::Center Center;
    std::vector<Enemy*>enemylist;
    std::vector<Player::Bullet*>bulletlist;
    std::vector<Obj*>objlist;
    Spawn Level;
    Render Render;

    ExMessage msg;//创建对象与结构体

    BeginBatchDraw();//开始绘制

	bool game_start = false;
    mciSendString(_T("play start_menu repeat from 0"), NULL, 0, NULL);
    while (!game_start) {
        DWORD start_time = GetTickCount();
        while (peekmessage(&msg))
        {
            cleardevice();
			putimage_alpha(Vector2(0, 0), &TouhouMaterial.MenuBG);
            static TCHAR str[64];
            _stprintf_s(str, _T("按空格键开始"));
            settextcolor(RGB(225, 175, 45));
            outtextxy(ScreenWidth / 2, ScreenHeight / 2, str);
            FlushBatchDraw();
            if (msg.message == WM_KEYUP && msg.vkcode == VK_SPACE)
            {
				game_start = true;
                break;
            }
            if (msg.message == WM_KEYUP && msg.vkcode == VK_ESCAPE)
            {
                game_start = true;
				running = false;
                break;
            }
        }
        DWORD end_time = GetTickCount();
        DWORD delta_time = end_time - start_time;
        if (delta_time < delta)
        {
            Sleep(delta - delta_time);
        }
    }
    mciSendString(_T("pause start_menu"), NULL, 0, NULL);
    MusicPlay();

    while (running) {
        DWORD start_time = GetTickCount();

        //玩家操作检测
        while (peekmessage(&msg))
        {
            Koishi.ProcessEvent(msg);
            if (msg.message == WM_KEYUP && msg.vkcode == VK_ESCAPE) running = false;
        }

        Level.ObjectLifeJudgement(enemylist, bulletlist, Koishi, Center, objlist);
		Level.ObjectSpawn(enemylist, bulletlist, Koishi, Center, objlist);
		Level.ObjectMove(enemylist, bulletlist, Koishi, Center, objlist);

		cleardevice();//清除上一帧屏幕绘制内容

        //渲染
        Render.DrawPicture(TouhouMaterial, Koishi, Center, enemylist, bulletlist, objlist);
        //score += 1;
        if (score >= target_score) { target_score += 300000*pow(2,score_bonus); score_bonus++; Koishi.HP++; mciSendString(_T("play player_extend from 0"), NULL, 0, NULL); }
        Render.DrawTextTip(Koishi);

		FlushBatchDraw();//将绘制画面缓存
      
        if (game_over) {
            std::wstring str = L"pause bgm0";
            int bgm_num_stop = (wave / boss_wave) % 5 + 1;
            str += (std::to_wstring(bgm_num_stop));
            mciSendString(str.c_str(), NULL, 0, NULL);
            mciSendString(_T("play game_over repeat from 0"), NULL, 0, NULL);

            std::wstring gameover_tip = L"感谢测试 ( *^ ▽ ^* )\n您的最终得分为";
            gameover_tip += (std::to_wstring(score) + L" ！\n");
            MessageBox(GetHWnd(), gameover_tip.c_str(), _T("满身疮痍"), MB_OK);
            running = false;
        }
        
        DWORD end_time = GetTickCount();
        DWORD delta_time = end_time - start_time;
        if (delta_time < delta)
        {
            Sleep(delta - delta_time);
        }
    }

    delete atlas_Koishi;    delete atlas_left_Koishi;       delete atlas_right_Koishi;
    delete atlas_BlueFairy; delete atlas_BlueFairy_left;   delete atlas_BlueFairy_right;
	delete atlas_RedFairy;  delete atlas_RedFairy_left;     delete atlas_RedFairy_right;
    delete atlas_GreatFairy;    delete atlas_GreatFairy_left;    delete atlas_GreatFairy_right;
	delete atlas_Boss;    delete atlas_Boss_left;       delete atlas_Boss_right;
	delete atlas_bullet_main; delete atlas_bullet_sub;
    delete atlas_danmu_red_small;   delete atlas_danmu_blue_small;    delete atlas_danmu_green_small;
    delete atlas_Troll;
    delete atlas_item_hp;    delete atlas_item_power;    delete atlas_item_point;
    delete atlas_SP_POWER; delete atlas_SP_HEALTH;

    EndBatchDraw();//将绘制画面刷新到屏幕

    return 514;
}
